package miniBanco.Core;

import java.util.ArrayList;
import java.util.List;

import miniBanco.Exceptions.HandledException;

public class Cuenta extends DomainObject {
   //Privados
   private TipoCuenta tipoCuenta;
   private Moneda moneda;
   private List<Movimiento> movimientos;
   private Cliente cliente;
   private int cbu;
   private float saldo;
   private boolean activa;
   //
   //Constructor
   public Cuenta()
   {
	   movimientos = new ArrayList<Movimiento>();
   }
   public Cuenta(Moneda moneda,int cbu,TipoCuenta tipoCuenta)
   {
	   this.moneda = moneda;
	   this.cbu = cbu;
	   this.tipoCuenta = tipoCuenta;
	   setSaldo(0);
	   activa = true;
	   movimientos = new ArrayList<Movimiento>();
   }
   public Cuenta(Cliente cliente,Moneda moneda,int cbu,TipoCuenta tipoCuenta)
   {
	   this(moneda,cbu,tipoCuenta);
   }
   //
   //Getters
	public TipoCuenta getTipoCuenta() {
		return tipoCuenta;
	}
	
	public Moneda getMoneda() {
		return moneda;
	}
	
	public void setMovimientos(List<Movimiento> movimientos) {
		this.movimientos = movimientos;
		for(Movimiento m:movimientos)
		{
			m.setCuenta(this);
		}
	}
	
	public List<Movimiento> getMovimientos() {
		return movimientos;
	}
	
	public Cliente getCliente() {
		return cliente;
	}
	
	public int getNroCuenta() {
		return cbu;
	}


	public boolean EsActiva()
	{
		return activa == true;
	}


	public float getSaldo() {
		
		return saldo;
	}
   //
   //Metodos
	
	public void TransferirDinero(Cuenta cuentaDestino,float importe)
	{
		if(cuentaDestino == null)
		{
			throw new HandledException("Debe especificar una cuenta destino");
		}
		if(cuentaDestino.getID() == this.getID())
		{
			throw new HandledException("La cuenta de destino no puede ser la misma que la de origen.");
		}
		
		this.Extraer(importe);	
		cuentaDestino.Depositar(importe);
	}
	
	public void Desactivar()
	{
		if(activa)
		{
			isDirty = true;
			activa = false;
		}

	}
	public void Activar()
	{
		isDirty = true;
		activa = true;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + cbu;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cuenta other = (Cuenta) obj;
		if (cbu != other.cbu)
			return false;
		return true;
	}
	public void Extraer(float importe) {
		if(!EsActiva())
			throw new HandledException("La cuenta no esta activa.");
		
		if(getSaldo() < importe)
			throw new HandledException("El saldo de la cuenta es menor al importe");
		
	
		setSaldo(getSaldo() - importe);
		Movimiento mov = new Movimiento(this,TipoConcepto.Extracciones,importe);
		movimientos.add(mov);
	}
	public void Depositar(float importe)
	{
		if(!EsActiva())
			throw new HandledException("La cuenta no esta activa");
		
		setSaldo(getSaldo() + importe);
		Movimiento mov = new Movimiento(this,TipoConcepto.Deposito,importe);
		movimientos.add(mov);
	}
	public boolean getEstado()
	{
		return activa;
	}
	public void setSaldo(float saldo) {
		isDirty = true;
		this.saldo = saldo;
	}
	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

}
